package com.zigin.healthcard.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.tencent.healthcard.HealthCardServer;
import com.tencent.healthcard.impl.HealthCardServerImpl;
import com.tencent.healthcard.model.CommonIn;
import com.tencent.healthcard.model.HealthCardInfo;
import com.tencent.healthcard.model.ReportHISData;
import com.zigin.healthcard.model.HealthCardUser;
import com.zigin.healthcard.util.Constant;
import com.zigin.healthcard.vo.HealthCardInfoVo;
import net.zigin.commons.util.AssertUtil;
import net.zigin.commons.util.ReflectUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 该接口用于获取接口调用凭证appToken，appToken是其他所有接口的调用凭证，是公共参数commonIn之一。
 * <p>
 * ● 通过该接口获取appToken时，appToken参数不校验，可以为空；
 * <p>
 * ● appToken有效期7200秒，有效期内多次调用该接口，会导致token刷新，旧token将失效。
 * <p>
 * 注意：调用接口前，请先在网站配置公网IP白名单，详见开发指南。
 */
@Service
public class HealthCardService {

    @Value("${healthCard.appId}")
    private String appId;
    @Value("${healthCard.appSecret}")
    private String appSecret;
    @Value("${healthCard.hospitalId}")
    private String hospitalId;


    @Autowired
    private HealthCardInfoService healthCardInfoService;

    @Autowired
    private HealthCardUserService healthCardUserService;


    /**
     * 调用获取接口调用凭证appToken接口
     */
    public JSONObject getAppToken() {
        HealthCardServerImpl healthCard = new HealthCardServerImpl(this.appSecret);
        //构造公共输入参数commonIn
        String appToken = "";
        CommonIn commonIn = createCommonIn(appToken);
        //构造请求参数req
        //调用接口
        JSONObject appTokenObj = healthCard.getAppToken(commonIn, this.appId);
        //打印响应
        System.out.println("appToken:" + appTokenObj.toJSONString());
        return appTokenObj;
    }

    /**
     * 接口：通过健康卡授权码获取健康卡接口
     */
    public JSONObject getHealthCardByHealthCode(String appToken, String healthCode) {
        AssertUtil.isNull(appToken, Constant.VALI_APP_TOKEN_MSG);
        //appSecret
        HealthCardServerImpl healthCard = new HealthCardServerImpl(this.appSecret);
        //构造公共输入参数commonIn
        CommonIn commonIn = createCommonIn(appToken);
        //构造请求参数req
        //调用接口
        JSONObject healthCardInfoRsp = healthCard.getHealthCardByHealthCode(commonIn, healthCode);
        //打印响应
        System.out.println(JSON.toJSONString(healthCardInfoRsp));
        return healthCardInfoRsp;
    }

    /**
     * 接口：OCR接口
     */
    public JSONObject toOcr(String appToken, String imageContent) {
        AssertUtil.isNull(appToken, Constant.VALI_APP_TOKEN_MSG);
        //appSecret
        HealthCardServerImpl healthCard = new HealthCardServerImpl(this.appSecret);
        //构造公共输入参数commonIn
        CommonIn commonIn = createCommonIn(appToken);
        //构造请求参数req
        //24K图片
        //调用接口
        JSONObject idCardInfo = healthCard.ocrInfo(commonIn, imageContent);
        //打印响应
        System.out.println(JSON.toJSONString(idCardInfo));
        return idCardInfo;
    }

    /**
     * 接口：注册健康卡接口
     */
    public JSONObject register(String appToken, HealthCardInfoVo healthCardInfoReq) {
        //验证数据是否合法
        AssertUtil.isNull(appToken, Constant.VALI_APP_TOKEN_MSG);
        validatePolicyInfoVo(healthCardInfoReq);
        //appSecret
        HealthCardServerImpl healthCard = new HealthCardServerImpl(this.appSecret);
        //构造公共输入参数commonIn
        CommonIn commonIn = createCommonIn(appToken);
        //构建healthCardInfo用于调用接口需要的参数类型
        HealthCardInfo healthCardInfo = new HealthCardInfo();
        ReflectUtil.copyProperties(healthCardInfoReq, healthCardInfo);
        //调用接口
        JSONObject healthCardInfoRsp = healthCard.registerHealthCard(commonIn, healthCardInfo);
        //打印响应
        System.out.println(JSON.toJSONString(healthCardInfoRsp));
        //查看返回是否成功，成功则存储数据到本地，否则返回错误信息
        JSONObject commonOut = healthCardInfoRsp.getJSONObject("commonOut");
        if (0 == commonOut.getInteger("resultCode") && "成功".equals(commonOut.getString("errMsg"))) {
            //保存用户信息
            HealthCardUser healthCardUser = saveHealthCardUser(healthCardInfoReq);
            //保存健康卡信息
            saveHealthCardInfo(healthCardInfoReq, healthCardInfoRsp, healthCardUser);

        }
        JSONObject rsp = healthCardInfoRsp.getJSONObject("rsp");
        String healthCardId = healthCardInfoRsp.getString("healthCardId");
        //二维码用于返回前端
        String qrCodeText = healthCardInfoRsp.getString("qrCodeText");
        //提交平台绑定healthCode和hospital的关系
        bindCard(appToken, this.hospitalId, qrCodeText);
        return healthCardInfoRsp;
    }

    private void saveHealthCardInfo(HealthCardInfoVo healthCardInfoReq, JSONObject healthCardInfoRsp, HealthCardUser healthCardUser) {
        //com.zigin.healthcard.model.HealthCardInfo healthCardInfo基础值赋值
        com.zigin.healthcard.model.HealthCardInfo healthCardInfo = new com.zigin.healthcard.model.HealthCardInfo();
        ReflectUtil.copyProperties(healthCardInfoReq, healthCardInfo);
        //健康码
        JSONObject rsp = healthCardInfoRsp.getJSONObject("rsp");
        String healthCardId = healthCardInfoRsp.getString("healthCardId");
        //二维码用于返回前端
        String qrCodeText = healthCardInfoRsp.getString("qrCodeText");
        String phid = healthCardInfoRsp.getString("phid");
        String adminExt = healthCardInfoRsp.getString("adminExt");
        healthCardInfo.setHealthCardId(healthCardId);
        healthCardInfo.setQrCodeText(qrCodeText);
        healthCardInfo.setPhid(phid);
        healthCardInfo.setAdminExt(adminExt);
        //存储healthCode和hospital的映射关系
        String uuid = UUID.randomUUID().toString().replaceAll("-", "").toUpperCase();
        healthCardInfo.setId(uuid);
        healthCardInfo.setHospatilId(this.hospitalId);
        healthCardInfo.setUserId(healthCardUser.getId());
        healthCardInfoService.insert(healthCardInfo);
    }

    private HealthCardUser saveHealthCardUser(HealthCardInfoVo healthCardInfoReq) {
        //构建用户信息用于存储在本地数据库中
        HealthCardUser healthCardUser = new HealthCardUser();
        ReflectUtil.copyProperties(healthCardInfoReq, healthCardUser);
        healthCardUserService.insert(healthCardUser);
        return healthCardUser;
    }


    /**
     * 接口：绑定健康卡和院内ID关系接口
     */
    public JSONObject bindCard(String appToken, String patid, String qrCodeText) {
        //appSecret
        HealthCardServerImpl healthCard = new HealthCardServerImpl(this.appSecret);
        //构造公共输入参数commonIn
        CommonIn commonIn = createCommonIn(appToken);
        //构造请求参数req
        //调用接口
        JSONObject bindCardRelation = healthCard.bindCardRelation(commonIn, patid, qrCodeText);
        //打印响应
        System.out.println(JSON.toJSONString(bindCardRelation));
        return bindCardRelation;
    }

    /**
     * 接口：通过健康卡授权码获取健康卡接口
     */
    public JSONObject healthCode(String appToken, String healthCode) {
        AssertUtil.isNull(appToken, Constant.VALI_APP_TOKEN_MSG);
        //appSecret
        HealthCardServerImpl healthCard = new HealthCardServerImpl(this.appSecret);
        //构造公共输入参数commonIn
        CommonIn commonIn = createCommonIn(appToken);
        //构造请求参数req
        //调用接口
        JSONObject healthCardInfoRsp = healthCard.getHealthCardByHealthCode(commonIn, healthCode);
        //打印响应
        System.out.println(JSON.toJSONString(healthCardInfoRsp));
        //健康码
        String healthCardId = healthCardInfoRsp.getString("healthCardId");
        //查询his有没有该健康卡的映射，如果没有新建增加到本地
        Map<String, Object> param = new HashMap<String, Object>();
        param.put("healthCardId", healthCardId);
        //二维码用于返回前端
        String qrCodeText = healthCardInfoRsp.getString("qrCodeText");
        /*if (healthCodeService.selectCount(param) == 0) {
            saveHealthCodeAndHospital(requestId, healthCardId, this.hospitalId);
        }*/
        bindCard(appToken, this.hospitalId, qrCodeText);
        return healthCardInfoRsp;
    }

    /**
     * 接口：注册批量健康卡接口
     */
    public JSONObject Test_batch(String appToken, List<HealthCardInfo> healthCardItems) {
        //appSecret
        HealthCardServerImpl healthCard = new HealthCardServerImpl(this.appSecret);
        //构造公共输入参数commonIn
        CommonIn commonIn = createCommonIn(appToken);
        //调用接口
        JSONObject healthCardInfosRsp = healthCard.registerBatchHealthCard(commonIn, healthCardItems);
        //打印响应
        System.out.println(JSON.toJSONString(healthCardInfosRsp));
        return healthCardInfosRsp;
    }

    private CommonIn createCommonIn(String appToken) {
        String requestId = UUID.randomUUID().toString().replaceAll("-", "").toUpperCase();
        int channelNum = 0;
        CommonIn commonIn = new CommonIn(appToken, requestId, this.hospitalId, channelNum);
        return commonIn;
    }

    private void validatePolicyInfoVo(HealthCardInfoVo healthCardInfoReq) {
        AssertUtil.isNull(healthCardInfoReq.getWechatCode(), Constant.VALI_WECHAT_CODE_MSG);
        AssertUtil.isNull(healthCardInfoReq.getName(), Constant.VALI_NAME_MSG);
        AssertUtil.isNull(healthCardInfoReq.getGender(), Constant.VALI_GENDER_MSG);
        AssertUtil.isNull(healthCardInfoReq.getNation(), Constant.VALI_NATION_MSG);
        AssertUtil.isNull(healthCardInfoReq.getBirthday(), Constant.VALI_BIRTHDAY_MSG);
        AssertUtil.isNull(healthCardInfoReq.getIdNumber(), Constant.VALI_ID_NUMBER_MSG);
        AssertUtil.isNull(healthCardInfoReq.getIdType(), Constant.VALI_ID_TYPE_MSG);
        AssertUtil.isNull(healthCardInfoReq.getPhone1(), Constant.VALI_PHONE1_MSG);

    }


    public void saveHealthCodeAndHospital(String id, String healthCardId, String hospitalId) {
      /*  HealthCode healthCode = new HealthCode();
        healthCode.setId(id);
        healthCode.setHealthCode(healthCardId);
        healthCode.setHospitalId(this.hospitalId);
        healthCodeService.insert(healthCode);*/
    }

    private HealthCardUser createHealthCardUser(HealthCardInfoVo healthCardInfoReq) {
        HealthCardUser healthCardUser = new HealthCardUser();
        ReflectUtil.copyProperties(healthCardInfoReq, healthCardUser);
        return healthCardUser;

    }

    public JSONObject getOrderId(String appToken, String qrCodeText) {
        /**
         * 接口：获取卡包订单ID接口
         */
        //appSecret
        HealthCardServerImpl healthCard = new HealthCardServerImpl(this.appSecret);
        //构造公共输入参数commonIn
        CommonIn commonIn = createCommonIn(appToken);
        //调用接口
        JSONObject orderId = healthCard.getOrderIdByOutAppId(commonIn, this.appId, qrCodeText);

        //打印响应
        System.out.println(JSON.toJSONString(orderId));
        return orderId;
    }

    public JSONObject On_lineReportHISData(String appToken,HealthCardInfoVo healthCardInfoVo,String scene,String department,String cardChannel,String cardCostTypes) {

        /**
         * 接口：用卡数据监测接口
         */
        //appSecret
        HealthCardServerImpl healthCard=new HealthCardServerImpl(this.appSecret);
        //构造公共输入参数commonIn
        CommonIn commonIn = createCommonIn(appToken);
        //构造请求参数req
        ReportHISData reportHISData=new ReportHISData();
        reportHISData.setQrCodeText(healthCardInfoVo.getQrCodeText());
        reportHISData.setIdCardNumber(healthCardInfoVo.getIdNumber());
        reportHISData.setName(healthCardInfoVo.getName());
        //date型数据转换成String
        String time = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
        reportHISData.setTime(time);
        reportHISData.setHospitalCode(this.hospitalId);
        reportHISData.setScene(scene);
        reportHISData.setDepartment(department);
        reportHISData.setCardChannel(cardChannel);
        reportHISData.setCardType(healthCardInfoVo.getIdType());
        reportHISData.setCardCostTypes(cardCostTypes);
        //调用接口
        JSONObject reportHISDataRsp=healthCard.reportHISData(commonIn,reportHISData);
        //打印响应
        System.out.println(JSON.toJSONString(reportHISDataRsp));

        return reportHISDataRsp;
    }


    /**
     * 接口：通过健康卡二维码获取健康卡接口
     * @param qrCodeText 二维码文本
     * @param appToken 用户凭证
     */
    public JSONObject getQRCode(String qrCodeText,String appToken) {

        //appSecret
        HealthCardServerImpl healthCard=new HealthCardServerImpl(this.appSecret);
        //构造公共输入参数commonIn
        CommonIn commonIn = createCommonIn(appToken);
        //调用接口
        JSONObject healthCardInfoRsp=healthCard.getHealthCardByQRCode(commonIn,qrCodeText);
        //打印响应
        System.out.println(JSON.toJSONString(healthCardInfoRsp));
        return healthCardInfoRsp;
    }


    /**
     * 接口：获取卡包订单ID接口
     * @param appId ISV用户凭证
     * @param qrCodeText 二维码文本
     * @param appToken 用户凭证
     */
    public JSONObject getOrderId(String appId,String qrCodeText,String appToken){
        //appSecret
        HealthCardServerImpl healthCard=new HealthCardServerImpl(this.appSecret);
        //构造公共输入参数commonIn
        CommonIn commonIn = createCommonIn(appToken);
        //调用接口
        JSONObject orderId=healthCard.getOrderIdByOutAppId(commonIn,appId,qrCodeText);
        //打印响应
        System.out.println(JSON.toJSONString(orderId));
        return orderId;
    }

    /**
     * 接口：获取动态二维码接口
     * @param healthCardId 健康卡ID
     * @param idType 证件类型
     * @param idNumber 证件号码
     * @param appToken 用户凭证
     */
    public JSONObject getDynamicQRCode(String healthCardId,String idType,String idNumber,String appToken){
        //appSecret
        HealthCardServerImpl healthCard=new HealthCardServerImpl(this.appSecret);
        //构造公共输入参数commonIn
        CommonIn commonIn = createCommonIn(appToken);
        //调用接口
        JSONObject dynamicQRCode=healthCard.getDynamicQRCode(commonIn,healthCardId,idType,idNumber);
        //打印响应
        System.out.println(JSON.toJSONString(dynamicQRCode));
        return dynamicQRCode;
    }
}
